//标题
Vue.component('ylTitle', {
    template: `<div :style="{height,lineHeight:height,backgroundColor}" style="display: flex; align-items: center; justify-content: space-between;" >
        <div :style="{textAlign, fontWeight,width:textWidth,backgroundColor:data.textBackgroundColor,borderTop,borderBottom,borderLeft,borderRight,
            boxSizing:'border-box',boxShadow:data.boxShadow,color}">{{data.title}}</div>
        <div class="operation"><slot></slot></div>
    </div>`,
    mixins: [global],
    props: {
        config: {
            type: Object,
            default: () => ({})
        }
    },
    computed: {
        data() {
            return {
                title: this.config.title || '',
                height: this.config.height || 46,
                heightUnit: this.config.heightUnit || 'px',
                fontWeight: this.config.fontWeight || 'bold',
                backgroundColor: this.config.backgroundColor || 'rgb(245,245,245)',
                textBackgroundColor: this.config.textBackgroundColor || '#fff',
                textAlign: this.config.textAlign || 'center',
                textWidth: this.config.textWidth || 200,
                textWidthUnit: this.config.textWidthUnit || 'px',
                color: '#000',
                borderTopWidth: this.config.borderTopWidth || 2.5,
                borderTopWidthUnit: this.config.borderTopWidthUnit || 'px',
                borderTopStyle: this.config.borderTopStyle || 'solid',
                borderTopColor: this.config.borderTopColor || '#67C23A',

                borderBottomWidth: this.config.borderBottomWidth || 0,
                borderBottomWidthUnit: this.config.borderBottomWidthUnit || '',
                borderBottomStyle: this.config.borderBottomStyle || '',
                borderBottomColor: this.config.borderBottomColor || '',

                borderLeftWidth: this.config.borderLeftWidth || 0,
                borderLeftWidthUnit: this.config.borderLeftWidthUnit || '',
                borderLeftStyle: this.config.borderLeftStyle || '',
                borderLeftColor: this.config.borderLeftColor || '',

                borderRightWidth: this.config.borderRightWidth || 0,
                borderRightWidthUnit: this.config.borderRightWidthUnit || '',
                borderRightStyle: this.config.borderRightStyle || '',
                borderRightColor: this.config.borderRightColor || '',
                boxShadow: this.config.boxShadow ? '0 1px 6px rgba(0, 0, 0, 0.15)' : ''
            }
        },
        textWidth() {
            return this.data.textWidth + this.data.textWidthUnit;
        },
    },
})
//单选框
Vue.component('ylRadio', {
    template: `<el-radio-group v-model="internalValue" @change="handle" :size="size" :disabled="disabled">
        <el-radio :disabled="item.disabled" :label="item.value" v-for="(item,index) in options" :border="border" :key="index">{{item.label}}</el-radio>
      </el-radio-group>`,
    props: {
        value: {
            type: [String, Number],
            default: ''
        },
        config: {
            type: Object,
            default: () => ({})
        }
    },
    data() {
        return {
            internalValue: this.value,//同步传入参数
        }
    },
    computed: {
        options() { return this.config.options || [] },//边框
        disabled() { return this.config.disabled || false },//禁用属性
        border() { return this.config.border || false },//是否带边框
        size() { return this.config.size || '' },//尺寸
        type() { return this.config.type || 'text' },//文本框
    },
    watch: {
        internalValue(newVal) {
            this.$emit('input', newVal);
        }
    },
    methods: {
        handle(val) {
            this.$emit('change', val);
        },
    },
})
//多选框
Vue.component('ylCheckbox', {
    template: `<el-checkbox-group v-model="internalValue" size="small" :disabled="disabled">
        <el-checkbox :disabled="item.disabled" :label="item.value" v-for="(item,index) in options" :border="border" :key="index">{{item.label}}</el-checkbox>
      </el-checkbox-group>`,
    props: {
        value: {
            type: Array,
            default: []
        },
        config: {
            type: Object,
            default: () => ({})
        }
    },
    data() {
        return {
            internalValue: this.value,//同步传入参数
        }
    },
    computed: {
        options() { return this.config.options || [] },//边框
        disabled() { return this.config.disabled || false },//禁用属性
        border() { return this.config.border || false },//是否带边框
        size() { return this.config.size || '' },//尺寸
        type() { return this.config.type || 'text' },//文本框
    },
    watch: {
        internalValue(newVal) {
            this.$emit('input', newVal);
        }
    },
    methods: {
        handle(val) {
            this.$emit('change', val);
        },
    },
})
//输入框
Vue.component('ylInput', {
    template: `<el-input :style="{width}" :type="type" @input="updateValue" v-model="internalValue" :disabled="disabled" :clearable="clearable" :show-password="showPassword" 
    :placeholder="placeholder" :show-password="showPassword" :suffix-icon="suffixIcon" :prefix-icon="prefixIcon"></el-input>`,
    props: {
        value: {
            type: [String, Number],
            default: ''
        },
        config: {
            type: Object,
            default: () => ({})
        }
    },
    data() {
        return {
            internalValue: this.value,//同步传入参数
        }
    },
    computed: {
        disabled() { return this.config.disabled || false },//禁用属性
        clearable() { return this.config.clearable || false },//清除属性
        placeholder() { return this.config.placeholder || '' },//未选提示
        showPassword() { return this.config.showPassword || false },//密码框
        suffixIcon() { return this.config.suffixIcon || '' },//尾部图标
        prefixIcon() { return this.config.prefixIcon || '' },//首部图标
        width() { return this.config.width + this.config.widthUnit },
        type() { return this.config.type || 'text' },//文本框
    },
    methods: {
        handle(val) {
            this.$emit('change', val)
        },
        updateValue(val) {
            this.$emit('input', val);
        },
    },
})
//计数器
Vue.component('ylInputNumber', {
    template: `<el-input-number v-model="internalValue" @change="handle" @input="updateValue" :min="min" :max="max" :size="size"
        :step="step" :step-strictly="stepStrictly" :placeholder="placeholder" :disabled="disabled"></el-input-number>`,
    props: {
        value: {
            type: Number,
            default: 0
        },
        config: {
            type: Object,
            default: () => ({})
        }
    },
    data() {
        return {
            internalValue: this.value,//同步传入参数
        }
    },
    computed: {
        size() { return this.config.size || '' },//尺寸
        step() { return this.config.step || 1 },//步长
        min() { return this.config.min || -Infinity },//最小值
        max() { return this.config.max || Infinity },//最大值
        stepStrictly() { return this.config.stepStrictly || false },//严格步数
        disabled() { return this.config.disabled || false },//禁用属性
        placeholder() { return this.config.placeholder || '' },//未选提示
    },
    methods: {
        handle(val) {
            this.$emit('change', val)
        },
        updateValue(val) {
            this.$emit('input', val);
        },
    },
})
//按钮--底层封装
Vue.component('ylbutton', {
    template: `<el-button :size="size" :plain="plain" :round="round" :circle="circle" :disabled="disabled" 
    :icon="icon" :autofocus="autofocus" :type="type" :loading="loading" @click="handle"><slot></slot></el-button>`,
    props: {
        data: {
            type: Object,
            default: () => ({})
        }
    },
    computed: {
        size() { return this.data.size || '' },
        type() { return this.data.type || '' },
        plain() { return this.data.plain || false },
        round() { return this.data.round || false },
        circle() { return this.data.circle || false },
        loading() { return this.data.loading || false },
        disabled() { return this.data.disabled || false },
        icon() { return this.data.icon || '' },
        autofocus() { return this.data.autofocus || false }
    },
    methods: {
        handle() {
            this.$emit('click')
        }
    }
})
//选择器
Vue.component('ylSelect', {
    template: `<el-select :style="{width}" @change="handle" :clearable="clearable" :multiple="multiple" :collapse-tags="collapseTags" :disabled="disabled" 
        :multiple-limit="multipleLimit" v-model="internalValue" :placeholder="placeholder" :size="size">
        <el-option v-for="(item,index) in options" :key="index" :label="item[isLabel]" :disabled="item[isDisabled]" :value="item[isValue]"></el-option>
    </el-select>`,
    props: {
        value: {
            type: [String, Number],
            default: ''
        },
        config: {
            type: Object,
            default: () => ({})
        }
    },
    data() {
        return {
            internalValue: this.value // 使用内部数据来同步 prop  
        }
    },
    computed: {
        options() { return this.config.options || [] },//可选数组
        size() { return this.config.size || '' },//尺寸
        disabled() { return this.config.disabled || false },//禁用属性
        clearable() { return this.config.clearable || false },//清除属性
        multiple() { return this.config.multiple || false },//多选属性
        collapseTags() { return this.config.collapseTags || false },//多选时是否将选中值按文字的形式展示
        multipleLimit() { return this.config.multipleLimit || 0 },//多选是最多可以选择的项目数，为0则不限制
        placeholder() { return this.config.placeholder || '' },//未选提示
        width() { return this.config.width + this.config.widthUnit },
        isValue() { return this.config.isValue || 'value' },//指定选项的值为选项对象的某个属性值
        isLabel() { return this.config.isLabel || 'label' },//指定选项的值为选项对象的某个属性值
        isDisabled() { return this.config.isDisabled || 'disabled' }//指定选项的禁用为选项对象的某个属性值
    },
    watch: {
        internalValue(newVal) {
            this.$emit('input', newVal)
        }
    },
    methods: {
        handle(val) {
            this.$emit('change', val)
        },
    },
})
//级联选择器
Vue.component('ylCascader', {
    template: `<el-cascader :style="{width}" v-model="internalValue" :options="options" :clearable="clearable" :show-all-levels="showAllLevels" :disabled="disabled" :size="size" :separator="separator" :placeholder="placeholder"
    :props="{ expandTrigger, multiple,value:isValue,label:isLabel,children:isChildren,disabled:isDisabled }"  :collapse-tags="collapseTags" @change="handle"></el-cascader>`,
    props: {
        value: {
            type: Array,
            default: []
        },
        config: {
            type: Object,
            default: () => ({})
        }
    },
    data() {
        return {
            internalValue: this.value // 使用内部数据来同步 prop  
        }
    },
    computed: {
        options() { return this.config.options || [] },//可选数组
        size() { return this.config.size || '' },//尺寸
        placeholder() { return this.config.placeholder || '请选择' },//占位符
        disabled() { return this.config.disabled || false },//禁用属性
        expandTrigger() { return this.config.expandTrigger || 'click' },//触发事件
        clearable() { return this.config.clearable || false },//清空
        showAllLevels() { return this.config.showAllLevels || true },//是否查看最后一级
        collapseTags() { return this.config.collapseTags || false },//多选时是否将选中值按文字的形式展示
        multiple() { return this.config.multiple || false },//是否多选
        separator() { return this.config.separator || '/' },//分隔符选项
        width() { return this.config.width + this.config.widthUnit },
        isValue() { return this.config.isValue || 'value' },//指定选项的值为选项对象的某个属性值
        isLabel() { return this.config.isLabel || 'label' },//指定选项的值为选项对象的某个属性值
        isChildren() { return this.config.isChildren || 'children' },//指定选项的值为选项对象的某个属性值
        isDisabled() { return this.config.isDisabled || 'disabled' }//指定选项的禁用为选项对象的某个属性值
    },
    watch: {
        internalValue(newVal) {
            this.$emit('input', newVal)
        }
    },
    methods: {
        handle(val) {
            this.$emit('change', val)
        }
    }
})
// 日期选择器
Vue.component('ylDatePicker', {
    template: `<el-date-picker :style="{width}" :format="format" :readonly="readonly" :value-format="valueFormat" :size="size" v-model="internalValue" :type="type" :clearable="clearable"
        :start-placeholder="startPlaceholder" :end-placeholder="endPlaceholder" :range-separator="rangeSeparator" :picker-options="pickerOptions" :disabled="disabled"
    :placeholder="placeholder" @change="handle"></el-date-picker>`,
    props: {
        value: {
            type: [String, Number],
            default: ''
        },
        config: {
            type: Object,
            default: () => ({})
        }
    },
    data() {
        return {
            internalValue: this.value
        }
    },
    computed: {
        size() { return this.config.size || '' },//尺寸
        type() { return this.config.type || 'datetime' },//类型
        format() {//显示在输入框中的格式
            let format = ''
            if (this.type == 'data') {
                format = 'yyyy-MM-dd'
            } else if (this.type == 'datatime') {
                format = 'yyyy-MM-dd HH:mm:ss'
            } else if (this.type == 'week') {
                format = 'yyyy 第 WW 周'
            }
            return this.config.format || format
        },
        valueFormat() { return this.config.valueFormat || '' },//绑定值的格式
        placeholder() { return this.config.placeholder || '请选择' },//非范围占位符
        startPlaceholder() { return this.config.startPlaceholder || '开始时间' },//范围选择时开始日期的占位符内容
        endPlaceholder() { return this.config.endPlaceholder || '结束时间' },//范围选择时结束日期的占位符
        rangeSeparator() { return this.config.rangeSeparator || '-' },//选择范围时的分隔符
        pickerOptions() { return this.config.pickerOptions || {} },//当前时间日期选择器
        readonly() { return this.config.readonly || false },//完全只读
        disabled() { return this.config.disabled || false },//禁用属性
        clearable() { return this.config.clearable || false },//清空
        width() { return this.config.width + this.config.widthUnit },//宽度
    },
    watch: {
        internalValue(newVal) {
            this.$emit('input', newVal)
        }
    },
    methods: {
        handle(val) {
            this.$emit('change', val)
        }
    }
})
// 时间选择器
Vue.component('ylTimePicker', {
    template: `<el-time-picker v-if="type=='picker'" :style="{width}" v-model="internalValue" :picker-options="{selectableRange,format}" :is-range="isRange" :arrow-control="arrowControl" 
    :placeholder="placeholder" :start-placeholder="startPlaceholder" :end-placeholder="endPlaceholder" :disabled="disabled" :clearable="clearable"></el-time-picker>
    <el-time-select v-else-if="type=='select'" :style="{width}" v-model="internalValue" :picker-options="{start,end,step,minTime,maxTime}" :placeholder="placeholder"></el-time-select>`,
    props: {
        value: {
            type: String,
            default: ''
        },
        config: {
            type: Object,
            default: () => ({})
        }
    },
    data() {
        return {
            internalValue: this.value
        }
    },
    computed: {
        type() { return this.config.type || 'picker' },//类型
        arrowControl() { return this.config.arrowControl || false },//是否使用箭头进行时间选择
        placeholder() { return this.config.placeholder || '请选择' },//非范围占位符
        startPlaceholder() { return this.config.startPlaceholder || '开始时间' },//范围时占位符
        endPlaceholder() { return this.config.endPlaceholder || '结束时间' },//范围时占位符
        selectableRange() { return this.config.selectableRange || '' },//可选时间段
        format() { return this.config.format || 'HH:mm:ss' },//时间格式化
        disabled() { return this.config.disabled || false },//禁用属性
        clearable() { return this.config.clearable || false },//清空
        isRange() { return this.config.isRange || false },//是否为时间范围
        start() { return this.config.start || '09:00' },//开始时间
        end() { return this.config.start || '18:00' },//结束时间
        step() { return this.config.step || '00:30' },//间隔时间
        minTime() { return this.config.minTime || '00:00' },//最小时间，小于该时间的时间段将被禁用
        maxTime() { return this.config.maxTime || '' },//最大时间，小于该时间的时间段将被禁用
        width() { return this.config.width + this.config.widthUnit },//宽度
    },
    watch: {
        internalValue(newVal) {
            this.$emit('input', newVal)
        }
    },
    methods: {
        handle(val) {
            this.$emit('change', val)
        }
    }
})
//表单容器
Vue.component('ylDescriptions', {
    template: `<el-descriptions :style="{marginLeft, marginRight, marginTop,marginBottom}" :column="column" border size="small">
        <el-descriptions-item  v-for="(item,index) in config.components" :key="index" :label="item.label">
            <el-form-item :prop="item.prop">
                <component v-model="form[item.prop]" :config="item.config" :is="item.title"></component>
            </el-form-item>
        </el-descriptions-item>
    </el-descriptions>`,
    mixins: [global],
    props: ['form', 'config'],
    computed: {
        column() { return this.config.column || 1 },
        marginLeft() { return this.config.left + this.config.leftUnit },
        marginRight() { return this.config.right + this.config.rightUnit },
        marginTop() { return this.config.top + this.config.topUnit },
        marginBottom() { return this.config.bottom + this.config.bottomUnit },
    },
})
//form表单
Vue.component('ylForm', {
    template: `<div :id="id" :class="[layer?'layer':'']" :style="{'border':layerBorder}">
    <el-form :model="data.form" :rules="data.rules" :ref="'form'+ id" inline-message="true" style="width: 100%">    
        <component v-for="(item,index) in data.components" :form="data.form" :config="item.config" :is="item.title"></component>
    <i v-show="layer&&SortableSwitch" style="position: absolute;top: 0;left: 0; z-index:999; color:#67C23A;" class="el-icon-rank"></i></div>`,
    mixins: [global],
    data() {
        return {

        }
    }
})
//form表单配置页
Vue.component('ylFormConfig', {
    template: `<el-collapse :id="'config'+id">
    <el-collapse-item :name="id">
        <template slot="title">
            <div class="table_titel">
                <div class="titel">表单配置</div>
            </div>
        </template>
        <div class="table_titel">
            <div class="titel">表单参数</div>
        </div>
        <div class="table_titel">
            <div class="titel">校验属性</div>
        </div>
        <div class="table_titel">
            <div class="titel">配置组件</div>
            <div class="operation">
               
            </div>
        </div>
        <el-descriptions :column="2" border size="small">
            <el-descriptions-item :label="组件选择">
                <el-select v-model="title" filterable clearable placeholder="请选择">
                    <el-option v-for="item in options"  :key="item.value" :label="item.label" :value="item.value"></el-option>
                </el-select>
            </el-descriptions-item>
            <el-descriptions-item :label="组件选择">
                <el-input v-model="item.structure" placeholder="请输入内容"></el-input>
            </el-descriptions-item>
            
        </el-descriptions>
    </el-collapse-item></el-collapse>`,
    mixins: [globalConfig],

})